package com.qqtech.qquan.hi.service;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Service;

import com.qqtech.core.common.enums.YesNoEnum;
import com.qqtech.core.common.util.StringUtil;
import com.qqtech.core.common.util.TimeUtil;
import com.qqtech.core.frame.dao.BaseDao;
import com.qqtech.core.frame.model.PageKit;
import com.qqtech.core.frame.model.PageOrder;
import com.qqtech.core.frame.model.Result;
import com.qqtech.core.frame.service.BaseServiceImpl;
import com.qqtech.qquan.hi.cache.HiSysParamCache;
import com.qqtech.qquan.hi.dao.HiRuleResultDao;
import com.qqtech.qquan.hi.enums.HiConst;
import com.qqtech.qquan.hi.enums.HiRuleCalculationTypeDictEnum;
import com.qqtech.qquan.hi.enums.HiRuleClassifyDictEnum;
import com.qqtech.qquan.hi.enums.HiRuleCompareDictEnum;
import com.qqtech.qquan.hi.enums.HiRuleResultAddDeleFlagDictEnum;
import com.qqtech.qquan.hi.enums.HiRuleResultWayDictEnum;
import com.qqtech.qquan.hi.model.HiRuleResult;
import com.qqtech.qquan.hi.model.HiRuleResultQuery;
import com.qqtech.qquan.hi.model.HiRuleResultVo;
import com.qqtech.qquan.hi.model.HiRuleVo;
import com.qqtech.qquan.hi.model.HiUserTaskVo;
import com.qqtech.qquan.push.service.PushBizzService;
import com.qqtech.qquan.user.enums.UserMoneyLogTypeDictEnum;
import com.qqtech.qquan.user.model.UserValueVo;
import com.qqtech.qquan.user.service.UserMoneyLogService;
import com.qqtech.qquan.user.service.UserValueService;

@Service
public class HiRuleResultServiceImpl extends BaseServiceImpl<HiRuleResult> implements HiRuleResultService {
	public static final Logger log = LoggerFactory.getLogger(HiRuleResultServiceImpl.class);

	@Resource
	private HiRuleResultDao hiRuleResultDao;

	@Resource
	private HiRuleService hiRuleService;

	@Resource
	private HiUserTaskService hiUserTaskService;
	@Resource
	private UserMoneyLogService userMoneyLogService;
	@Resource
	private UserValueService userValueService;
	@Resource
	private HiSysParamCache hiSysParamCache;
	@Resource
	private PushBizzService pushBizzService;

	@Override
	protected BaseDao<HiRuleResult> getBaseDao() {
		return hiRuleResultDao;
	}

	@Override
	public HiRuleResultVo getNewest(Integer userId, Integer classify, Integer classifyId) {
		if (userId == null) {
			return null;
		}
		HiRuleResultQuery q = new HiRuleResultQuery();
		q.setClassify(classify);
		q.setUserId(userId);
		q.setClassifyId(classifyId);
		Pageable pageKit = new PageKit(1, 1, new PageOrder(Direction.DESC, "updAt"),
				new PageOrder(Direction.DESC, "id"));
		Page<HiRuleResultVo> page = hiRuleResultDao.queryPageList(q, pageKit);
		if (page != null && page.getContent() != null && page.getContent().size() > 0) {
			List<HiRuleResultVo> list = page.getContent();
			return list.get(0);
		}
		return null;
	}

	@Override
	public int getCountByRuleId(Integer userId, Integer ruleId, Timestamp startAt, Timestamp endAt) {
		if (ruleId == null) {
			return 0;
		}
		HiRuleResultQuery q = new HiRuleResultQuery();
		q.setUserId(userId);
		q.setRuleId(ruleId);
		q.setStartAt(startAt);
		q.setEndAt(endAt);
		return hiRuleResultDao.queryCount(q);
	}

	@Override
	public int getCountByClassifyId(Integer userId, Integer classify, Integer classifyId, Timestamp startAt,
			Timestamp endAt) {
		if (classify == null) {
			return 0;
		}
		HiRuleResultQuery q = new HiRuleResultQuery();
		q.setUserId(userId);
		q.setClassify(classify);
		q.setClassifyId(classifyId);
		q.setStartAt(startAt);
		q.setEndAt(endAt);
		return hiRuleResultDao.queryCount(q);
	}

	@Override
	public Result handleSave(Integer userId, Integer classify, Integer classifyId, Integer times,
			HiRuleResultVo lastVo) {
		return handleSave(userId, classify, classifyId, times, lastVo, null);
	}

	@Override
	public Result handleSave(Integer userId, Integer classify, Integer classifyId, Integer times, HiRuleResultVo lastVo,
			BigDecimal value) {
		Result result = new Result();
		String enableStr = hiSysParamCache.get(HiConst.PARAMKEY_HI_ENABLE_DEFAULT);
		if (StringUtil.isNotBlank(enableStr) && YesNoEnum.NO.getCode() == Integer.parseInt(enableStr)) {
			result.addErr("荣誉系统未启用");
			return result;
		}
		if (userId == null) {
			result.addErr("userId不能为空");
		}
		if (classify == null) {
			result.addErr("classify不能为空");
		}
		if (times == null) {
			result.addErr("times不能为空");
		}
		if (result.checkForm()) {
			List<HiRuleVo> ruleList = hiRuleService.queryRuleByClassify(classify, YesNoEnum.YES.getCode());
			if (ruleList != null) {
				HiRuleResultVo newestResultVo = getNewest(userId, null, null);
				Integer quanValueTotal = 0;
				Integer honorValueTotal = 0;
				StringBuilder sbNames = new StringBuilder();
				StringBuilder pushMsg = new StringBuilder();
				for (HiRuleVo rule : ruleList) {
					Integer quanValue = 0; // 单次获得
					Integer honorValue = 0;
					if ((rule.getCompare().intValue() == HiRuleCompareDictEnum.EQUAL_TO.getCode()
							&& times.intValue() == rule.getCompareValue().intValue())
							|| (rule.getCompare().intValue() == HiRuleCompareDictEnum.GREATER_THAN.getCode()
									&& times.intValue() > rule.getCompareValue().intValue())
							|| (rule.getCompare().intValue() == HiRuleCompareDictEnum.LESS_THAN.getCode()
									&& times.intValue() < rule.getCompareValue().intValue())) {
						if (rule.getLimitQuantity().intValue() > 0) {
							int c = getCountByRuleId(userId, rule.getId(), null, null);
							if (c >= rule.getLimitQuantity().intValue()) {
								continue;
							}
						}
						if (rule.getLimitDayTimes().intValue() > 0) {
							Timestamp endAt = TimeUtil.now();
							Timestamp startAt = TimeUtil.startWithDays(endAt, 0);
							int c = getCountByRuleId(userId, rule.getId(), startAt, endAt);
							if (c >= rule.getLimitDayTimes().intValue()) {
								continue;
							}
						}
						if (rule.getCalculationType().intValue() == HiRuleCalculationTypeDictEnum.INTEGRAL.getCode()) {
							quanValue = rule.getQuanValue();
							honorValue = rule.getHonorValue();
						} else {
							// 按比例计算
							if (value == null) {
								value = BigDecimal.ZERO;
							}
							quanValue = Double.valueOf(Math.ceil(value.doubleValue() * rule.getQuanValue() / 100))
									.intValue();
							honorValue = Double.valueOf(Math.ceil(value.doubleValue() * rule.getHonorValue() / 100))
									.intValue();
						}
						quanValueTotal += quanValue;
						honorValueTotal += honorValue;
						if (rule.getQuanValue() != null && rule.getQuanValue().intValue() != 0) {
							if (StringUtil.isNotBlank(sbNames.toString())) {
								sbNames.append(";");
							}
							sbNames.append(rule.getName());
						}
						if (quanValue.intValue() > 0 || honorValue.intValue() > 0) {
							if (StringUtil.isNotBlank(pushMsg.toString())) {
								pushMsg.append(";");
							}
							pushMsg.append(rule.getName());
							String honorTips = "奖励";
							String quanTips = "奖励";
							if (honorValue.intValue() < 0) {
								honorTips = "扣减";
							}
							if (quanValue.intValue() < 0) {
								quanTips = "扣减";
							}
							if (honorValue.intValue() != 0 && quanValue.intValue() != 0) {
								if (honorTips.equals(quanTips)) {
									pushMsg.append("(" + honorTips + honorValue.intValue() + "荣誉值+"
											+ quanValue.intValue() + "圈币)");
								} else {
									pushMsg.append("(" + honorTips + honorValue.intValue() + "荣誉值+" + quanTips
											+ quanValue.intValue() + "圈币)");
								}
							} else if (honorValue.intValue() != 0) {
								pushMsg.append("(" + honorTips + honorValue.intValue() + "荣誉值)");
							} else if (quanValue.intValue() != 0) {
								pushMsg.append("(" + quanTips + quanValue.intValue() + "圈币)");
							}
						}
						// 保存明细
						HiRuleResult ruleResult = new HiRuleResult();
						ruleResult.setNewAt(TimeUtil.now());
						ruleResult.setUpdAt(ruleResult.getNewAt());
						ruleResult.setWay(HiRuleResultWayDictEnum.SYSTEM.getCode());
						ruleResult.setUserId(userId);
						ruleResult.setDesc(rule.getName());
						ruleResult.setHonorValue(honorValue);
						ruleResult.setQuanValue(quanValue);
						ruleResult.setRuleId(rule.getId());
						ruleResult.setClassify(classify);
						ruleResult.setClassifyId(classifyId);
						ruleResult.setAddDeleFlag(HiRuleResultAddDeleFlagDictEnum.ADD.getCode());
						if (lastVo == null) {
							ruleResult.setTimes(1);
						} else {
							ruleResult.setTimes(lastVo.getTimes() + 1);
						}
						if (newestResultVo == null) {
							ruleResult.setHonorBalance(honorValueTotal);
							ruleResult.setQuanBalance(quanValueTotal);
							ruleResult.setHasFinishTask(YesNoEnum.NO.getCode());
						} else {
							ruleResult.setHonorBalance(newestResultVo.getHonorBalance() + honorValueTotal);
							ruleResult.setQuanBalance(newestResultVo.getQuanBalance() + quanValueTotal);
							ruleResult.setHasFinishTask(newestResultVo.getHasFinishTask());
						}
						hiRuleResultDao.insert(ruleResult);
						if (rule.getTaskType().intValue() == 1) { // 新手任务
							hiUserTaskService.finishOneTask(userId, rule.getId());
						}
					}
				}
				if (newestResultVo == null || newestResultVo.getHasFinishTask().intValue() == YesNoEnum.NO.getCode()) {
					if (hiUserTaskService.isFinishAllTask(userId)) {
						handleFinishTask(userId);
					}
				}
				if (quanValueTotal != null && quanValueTotal.intValue() != 0) {
					String sbStr = sbNames.toString();
					if (StringUtil.isNotBlank(sbStr)) {
						sbStr = "荣誉任务获得:" + sbStr;
					}
					userMoneyLogService.addMoneyToUser(userId, quanValueTotal, sbStr, UserMoneyLogTypeDictEnum.QUAN);
				}
				if (honorValueTotal != null && honorValueTotal.intValue() != 0) {
					userValueService.alterHonorValue(userId, honorValueTotal);
				}
				if (StringUtil.isNotBlank(pushMsg.toString())) {
					pushBizzService.honorNotice(userId, pushMsg.toString());// 推送
				}
			} else {
				log.info("HiRuleResultServiceImpl.java handleSave：系统没有荣誉规则" + classify.toString());
			}
		}
		return result;
	}

	@Override
	public void handleFinishTask(Integer userId) {
		if (userId == null) {
			return;
		}
		HiUserTaskVo hiUserTaskVo = hiUserTaskService.getOneUserTask(userId, null);
		if (hiUserTaskVo == null) {
			return;
		}
		HiRuleResultVo lastResultVo = getNewest(userId, null, null);
		// 保存明细
		HiRuleResult ruleResult = new HiRuleResult();
		ruleResult.setNewAt(TimeUtil.now());
		ruleResult.setUpdAt(ruleResult.getNewAt());
		ruleResult.setWay(HiRuleResultWayDictEnum.SYSTEM.getCode());
		ruleResult.setUserId(userId);
		ruleResult.setDesc("完成所有新手任务");
		ruleResult.setHonorValue(hiUserTaskVo.getFinishHonorValue());
		ruleResult.setQuanValue(hiUserTaskVo.getFinishQuanValue());
		ruleResult.setClassify(HiRuleClassifyDictEnum.COMPLETE_NEW_TASK.getCode());
		List<HiRuleVo> ruleList = hiRuleService.queryRuleByClassify(HiRuleClassifyDictEnum.COMPLETE_NEW_TASK.getCode(),
				YesNoEnum.YES.getCode());
		if (ruleList != null && !ruleList.isEmpty()) {
			ruleResult.setRuleId(ruleList.get(0).getId());
		} else {
			ruleResult.setRuleId(0);
		}
		ruleResult.setClassifyId(null);
		ruleResult.setAddDeleFlag(HiRuleResultAddDeleFlagDictEnum.ADD.getCode());
		if (lastResultVo == null) {
			ruleResult.setHonorBalance(hiUserTaskVo.getFinishHonorValue());
			ruleResult.setQuanBalance(hiUserTaskVo.getFinishQuanValue());
		} else {
			ruleResult.setHonorBalance(lastResultVo.getHonorBalance() + hiUserTaskVo.getFinishHonorValue());
			ruleResult.setQuanBalance(lastResultVo.getQuanBalance() + hiUserTaskVo.getFinishQuanValue());
		}
		ruleResult.setTimes(1);
		ruleResult.setHasFinishTask(YesNoEnum.YES.getCode());
		hiRuleResultDao.insert(ruleResult);
		if (hiUserTaskVo.getFinishQuanValue() != null && hiUserTaskVo.getFinishQuanValue().intValue() != 0) {
			userMoneyLogService.addMoneyToUser(userId, hiUserTaskVo.getFinishQuanValue(), "完成所有新手任务",
					UserMoneyLogTypeDictEnum.QUAN);
		}
		if (hiUserTaskVo.getFinishHonorValue() != null && hiUserTaskVo.getFinishHonorValue().intValue() != 0) {
			userValueService.alterHonorValue(userId, hiUserTaskVo.getFinishHonorValue());
		}
		hiRuleResultDao.updateHasFinishTask(userId);
	}

	@Override
	public int queryTotalQuan(HiRuleResultQuery query) {
		return hiRuleResultDao.queryTotalQuan(query);
	}

	@Override
	public int queryTotalHonor(HiRuleResultQuery query) {
		return hiRuleResultDao.queryTotalHonor(query);
	}

	@Override
	public Page<HiRuleResultVo> queryPageList4Admin(HiRuleResultQuery query, Pageable pageable) {
		return hiRuleResultDao.queryPageList4Admin(query, pageable);
	}

	@Override
	public Result handleManualSave(Integer userId, Integer addDeleFlag, Integer honorValue, Integer quanValue,
			String desc, Integer adminUserId) {
		Result result = new Result();
		if (userId == null) {
			result.addErr("用户id不能为空");
		}
		if (addDeleFlag == null) {
			result.addErr("增减标识不能为空");
		} else if (!HiRuleResultAddDeleFlagDictEnum.isInScope(addDeleFlag)) {
			result.addErr("输入的增减标识不对");
		}
		if (honorValue == null) {
			result.addErr("荣誉值不能为空");
		} else if (honorValue.intValue() < 0) {
			result.addErr("输入的荣誉值必须大于0");
		}
		if (quanValue == null) {
			result.addErr("圈币值不能为空");
		} else if (quanValue.intValue() < 0) {
			result.addErr("输入的圈币值必须大于0");
		}
		if (desc == null || desc.trim().equals("")) {
			result.addErr("备注不能为空");
		}
		if (adminUserId == null) {
			result.addErr("后台操作人id不能为空");
		}
		if (result.checkForm()) {
			UserValueVo v = userValueService.getById(userId);
			int honorValueTotal = v.getHonorValue() == null ? 0 : v.getHonorValue().intValue();
			int quanValueTotal = v.getQuanValue() == null ? 0 : v.getQuanValue().intValue();
			if (addDeleFlag.intValue() == HiRuleResultAddDeleFlagDictEnum.DELE.getCode()) {
				if (honorValueTotal < honorValue) {
					honorValue = honorValueTotal;
				}
				if (quanValueTotal < quanValue) {
					quanValue = quanValueTotal;
				}
			}
			HiRuleResultVo lastResultVo = getNewest(userId, null, null);
			// 保存明细
			HiRuleResult ruleResult = new HiRuleResult();
			ruleResult.setNewAt(TimeUtil.now());
			ruleResult.setUpdAt(ruleResult.getNewAt());
			ruleResult.setWay(HiRuleResultWayDictEnum.ARTIFICIAL.getCode());
			ruleResult.setUserId(userId);
			ruleResult.setDesc(desc);
			ruleResult.setHonorValue(honorValue);
			ruleResult.setQuanValue(quanValue);
			ruleResult.setClassify(null);
			ruleResult.setRuleId(0);
			ruleResult.setClassifyId(null);
			ruleResult.setAddDeleFlag(addDeleFlag);
			if (lastResultVo == null) {
				ruleResult.setHonorBalance(honorValue);
				ruleResult.setQuanBalance(quanValue);
				ruleResult.setHasFinishTask(YesNoEnum.NO.getCode());
			} else {
				ruleResult.setHonorBalance(lastResultVo.getHonorBalance() + honorValue);
				ruleResult.setQuanBalance(lastResultVo.getQuanBalance() + quanValue);
				ruleResult.setHasFinishTask(lastResultVo.getHasFinishTask());
			}
			ruleResult.setTimes(1);
			ruleResult.setAdminUserId(adminUserId);
			hiRuleResultDao.insert(ruleResult);
			if (addDeleFlag.intValue() == HiRuleResultAddDeleFlagDictEnum.DELE.getCode()) {
				quanValue = -quanValue.intValue();
				honorValue = -honorValue.intValue();
			}
			if (quanValue.intValue() != 0) {
				userMoneyLogService.addMoneyToUser(userId, quanValue, desc, UserMoneyLogTypeDictEnum.QUAN);
			}
			if (honorValue.intValue() != 0) {
				userValueService.alterHonorValue(userId, honorValue);
			}
			if (honorValue.intValue() != 0 || quanValue.intValue() != 0) {
				StringBuilder pushMsg = new StringBuilder(desc);
				if (honorValue.intValue() != 0 && quanValue.intValue() != 0) {
					pushMsg.append("(" + honorValue.intValue() + "荣誉值+" + quanValue.intValue() + "圈币)");
				} else if (honorValue.intValue() != 0) {
					pushMsg.append("(" + honorValue.intValue() + "荣誉值)");
				} else if (quanValue.intValue() != 0) {
					pushMsg.append("(" + quanValue.intValue() + "圈币)");
				}
				pushBizzService.honorNotice(userId, pushMsg.toString());// 推送
			}
		}
		return result;
	}

}